﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System.Collections.Generic;
using System.Linq;
using System.IO;
using BrainTechLLC.WPF;
using System.Windows.Controls;
using System.Windows.Input;
using ImageAppViewModels;
using System;
using BrainTechLLC;
using BrainTechLLC.FilterExtensions;
using System.Windows;
using ImageAppDataModels;
using System.Diagnostics;

namespace WpfImageDuplicates
{
    public partial class ImageCollectionView : UserControl
    {
        protected List<FileImageViewModel> _copiedImages;

        public void ToggleSelection(FileImageViewModel vm, bool bringIntoView)
        {
            try
            {
                if (lstItems.SelectedItems.Contains(vm))
                {
                    lstItems.SelectedItems.Remove(vm);
                }
                else
                {
                    lstItems.SelectedItems.Add(vm);
                }

                if (bringIntoView)
                {
                    ThumbnailView tv = FindThumbView(vm);

                    if (tv == null)
                    {
                        Debug.WriteLine("BLAH");
                    }
                    if (tv != null)
                    {
                        tv.BringIntoView();
                    }
                }
                _lastSelected = vm;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public void SelectAndMoveTo(int indexNow, int targetIndex, ModifierKeys modifiers)
        {
            try
            {
                var selectedItems = Displayed.Where(o => o.IsSelected).ToList();
                _startLocation = indexNow;
                _endLocation = targetIndex;

                if (targetIndex < Displayed.Count && targetIndex >= 0)
                {
                    FileImageViewModel vmTarget = Displayed[targetIndex] as FileImageViewModel;

                    if (vmTarget != null)
                    {
                        if (_Rows == 0)
                        {
                            CalculateColumnsAndRows();
                        }

                        if ((modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
                        {
                            // handle shift key down - select everything in between the source & target
                            int indexEnd = IndexOf(vmTarget);
                            bool targetCurrentlySelected = selectedItems.Contains(vmTarget);
                            FileImageViewModel vmSel = null;

                            if (targetCurrentlySelected)
                            {
                                FileImageViewModel vmNow = Displayed[indexNow] as FileImageViewModel;
                                ToggleSelection(vmNow, false);
                            }

                            if (targetIndex > indexNow)
                            {
                                for (int i = targetCurrentlySelected ? targetIndex - 1 : targetIndex; i > indexNow; i--)
                                {
                                    vmSel = Displayed[i] as FileImageViewModel;
                                    ToggleSelection(vmSel, false);
                                }
                            }
                            else
                            {
                                for (int i = targetCurrentlySelected ? targetIndex + 1 : targetIndex; i < indexNow; i++)
                                {
                                    vmSel = Displayed[i] as FileImageViewModel;
                                    ToggleSelection(vmSel, false);
                                }
                            }
                        }
                        else if ((modifiers & ModifierKeys.Control) == ModifierKeys.Control)
                        {
                            bool targetCurrentlySelected = lstItems.SelectedItems.Contains(vmTarget);

                            if (targetCurrentlySelected)
                            {
                                FileImageViewModel vmNow = Displayed[indexNow] as FileImageViewModel;
                                ToggleSelection(vmNow, false);
                            }
                            else
                            {
                                ToggleSelection(vmTarget, false);
                            }
                        }
                        else
                        {
                            lstItems.SelectedItems.Clear();
                            lstItems.SelectedItems.Add(vmTarget);
                        }

                        int indexOfTarget = Displayed.IndexOf(vmTarget);
                        if (indexOfTarget - _Columns < _wrapPanel.firstVisibleItemIndex)
                        {
                            int rowsToMove = ((_wrapPanel.firstVisibleItemIndex - indexOfTarget) / _Rows) + 1;
                            ScrollHandler.Scroll(0D - (Convert.ToDouble(rowsToMove) * Settings.Values.ThumbHeight));
                        }
                        else if (indexOfTarget + _Columns > _wrapPanel.lastVisibleItemIndex)
                        {
                            int rowsToMove = ((indexOfTarget - _wrapPanel.lastVisibleItemIndex) / _Rows) + 1;
                            ScrollHandler.Scroll(0D + (Convert.ToDouble(rowsToMove) * Settings.Values.ThumbHeight));
                        }

                        _lastSelected = vmTarget;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private FileImageViewModel FindFirstThumbnailViewInUpperLeft()
        {
            return Displayed[_wrapPanel.firstVisibleItemIndex];
        }

        protected void MovePageUpOrDown(bool scrollUp, ModifierKeys modifiers)
        {
            try
            {
                int index = IndexOf(_lastSelected);
                int newIndex = index;
                if (scrollUp)
                {
                    newIndex = Math.Max(0, index - (_Columns * (Math.Max(_Rows, 3) - 2)));
                }
                else
                {
                    newIndex = Math.Min(Displayed.Count - 1, index + (_Columns * (Math.Max(_Rows, 3) - 2)));
                }

                SelectAndMoveTo(index, newIndex, modifiers);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public bool HandlePageUpDown(Key key, ModifierKeys modifiers)
        {
            // Console.WriteLine(string.Format("{0}/{1}/{2}", _lastSelected == null ? "None" : _lastSelected.FileNameOnly, _wrapPanel.firstVisibleItemIndex, _wrapPanel.lastVisibleItemIndex));
            try
            {
                if (key == Key.End)
                {
                    //ScrollHandler.ScrollBottom();

                    if ((modifiers & ModifierKeys.Control) == ModifierKeys.Control)
                    {
                        modifiers -= ModifierKeys.Control;
                    }
                    if (_lastSelected != null)
                    {
                        int index = IndexOf(_lastSelected);
                        SelectAndMoveTo(index, this.Displayed.Count - 1, modifiers);
                    }

                    return true;
                }
                else if (key == Key.Home)
                {
                    //ScrollHandler.ScrollTop();

                    if ((modifiers & ModifierKeys.Control) == ModifierKeys.Control)
                    {
                        modifiers -= ModifierKeys.Control;
                    }
                    if (_lastSelected != null)
                    {
                        int index = IndexOf(_lastSelected);
                        SelectAndMoveTo(index, 0, modifiers);
                    }

                    return true;
                }
                else if (key == Key.PageDown)
                {
                    //ScrollHandler.ScrollPageDown();

                    if (_lastSelected != null)
                    {
                        MovePageUpOrDown(false, modifiers);
                    }

                    return true;
                }
                else if (key == Key.PageUp)
                {
                    //ScrollHandler.ScrollPageUp();

                    if (_lastSelected != null)
                    {
                        MovePageUpOrDown(true, modifiers);
                    }

                    return true;
                }
                else if (key == Key.Right)
                {
                    if (_lastSelected != null)
                    {
                        int index = IndexOf(_lastSelected);
                        SelectAndMoveTo(index, index + 1, modifiers);
                        return true;
                    }
                }
                else if (key == Key.Left)
                {
                    if (_lastSelected != null)
                    {
                        int index = IndexOf(_lastSelected);
                        SelectAndMoveTo(index, index - 1, modifiers);
                        return true;
                    }
                }
                else if (key == Key.Up)
                {
                    if (_lastSelected != null)
                    {
                        int index = IndexOf(_lastSelected);
                        int perRow = CalcColumnsPerRow();
                        SelectAndMoveTo(index, index - perRow, modifiers);
                        return true;
                    }
                }
                else if (key == Key.Down)
                {
                    if (_lastSelected != null)
                    {
                        int index = IndexOf(_lastSelected);
                        int perRow = CalcColumnsPerRow();
                        int newIndex = (index + perRow >= Displayed.Count) ? Displayed.Count - 1 : index + perRow;
                        SelectAndMoveTo(index, newIndex, modifiers);
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            return false;
        }

        private void lstItems_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.Key == Key.Delete)
                {
                    var images = GetSelectedImages();
                    RequestDeleteMany.RaiseEvent(this, images);
                }                
                if (e.Key == Key.C && ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) == ModifierKeys.Control))
                {
                    _copiedImages = GetSelectedImages();
                }
                if (e.Key == Key.I && this._lastSelected != null)
                {
                    ImageCalculation calc = new ImageCalculation("Color Calc", (a, b, c, d) => ImageCalculation.AverageRedCalc(a, b, c, d));
                    var result = calc.Calculate(this._lastSelected.Thumbnail);
                    MessageBox.Show(result.ToString());
                    e.Handled = true;
                }
                if (e.Key == Key.V && ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) == ModifierKeys.Control))
                {
                    if (_copiedImages != null)
                    {
                        for (int n = 0; n < _copiedImages.Count; n++)
                        {
                            var image = _copiedImages[n];
                            var ext = Path.GetExtension(image.FileName);
                            var fileName = Path.GetFileNameWithoutExtension(image.FileName);
                            var dirName = Path.GetDirectoryName(image.FileName);
                            File.Copy(image.FileName, dirName + "\\" + fileName + "_copy" + ext);
                        }
                        _copiedImages = null;
                    }
                }
                if (HandlePageUpDown(e.Key, e.KeyboardDevice.Modifiers))
                {
                    e.Handled = true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        internal void HighlightLastSelected()
        {
            try
            {
                if (_lastSelected != null)
                {
                    lstItems.ScrollIntoView(_lastSelected);
                    _lastSelected.IsSelected = true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public void FilterByFileName(string fileName)
        {
            try
            {
                if (string.IsNullOrEmpty(fileName))
                {
                    lstItems.Filter(null);
                }
                else
                {
                    lstItems.Filter(o =>
                        {
                            FileImageViewModel vm = o as FileImageViewModel;
                            return (vm.FileName.IndexOf(fileName, StringComparison.OrdinalIgnoreCase) >= 0);
                        });
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}